import Cesium from '../Ces/Cesium'

class WeGeometryUtil {
  static createCubeGeometry(context, numLon, numLat, numPointOfLine = 3): any {
    const numLines = numLon * numLat // number of line
    const numVertexs = (numPointOfLine - 1) * numLines * 4

    const indices = []
    let idx = 0;
    for (let i = 0; i < numVertexs; i++) {
      if (i < numLines) {
        for (let k = 0; k < numPointOfLine - 1; k++) {
          indices[idx++] = (0 + 4 * k) * numLines + i
          indices[idx++] = (1 + 4 * k) * numLines + i
          indices[idx++] = (2 + 4 * k) * numLines + i

          indices[idx++] = (0 + 4 * k) * numLines + i
          indices[idx++] = (2 + 4 * k) * numLines + i
          indices[idx++] = (3 + 4 * k) * numLines + i
        }
      }
    }

    const geometry = new Cesium.Geometry({
      attributes: {
        position: new Cesium.GeometryAttribute({
          componentDatatype: Cesium.ComponentDatatype.BYTE,
          componentsPerAttribute: 1,
          values: new Uint8Array(numVertexs),
        }),
      },
      indices,
    })

    const attributeLocations = Cesium.GeometryPipeline.createAttributeLocations(geometry);
    const vertexArray = Cesium.VertexArray.fromGeometry({
      context,
      geometry,
      attributeLocations,
      bufferUsage: Cesium.BufferUsage.STATIC_DRAW,
    })

    return {
      vertexArray,
      attributeLocations,
    }
  }

  static createCubeGeometry1(context, numLon, numLat, numPointOfLine = 3): any {
    const numLines = numLon * numLat // number of line
    const numVertexsOfLine = numPointOfLine * 2
    const numVertexs = numVertexsOfLine * numLines

    const indices: number[] = []
    const lineIDS: boolean[] = []
    for (let i = 0; i < numVertexs; i++) {
      const lineID = Math.floor(i / numVertexsOfLine)
      const vertexID = i % numVertexsOfLine
      const vertexC = vertexID % numPointOfLine
      const vertexR = Math.floor(vertexID / numPointOfLine)

      if (!lineIDS[lineID]) {
        lineIDS[lineID] = true

        for (let j = 0; j < numPointOfLine - 1; j++) {
          const a = i + j
          const b = a + 1
          const c = a + numPointOfLine
          const d = c + 1
          indices.push(a); indices.push(c); indices.push(d)
          indices.push(a); indices.push(d); indices.push(b)
        }
      }
    }

    const geometry = new Cesium.Geometry({
      attributes: {
        position: new Cesium.GeometryAttribute({
          componentDatatype: Cesium.ComponentDatatype.BYTE,
          componentsPerAttribute: 1,
          values: new Uint8Array(numVertexs),
        }),
      },
      indices,
    })

    const attributeLocations = Cesium.GeometryPipeline.createAttributeLocations(geometry);
    const vertexArray = Cesium.VertexArray.fromGeometry({
      context,
      geometry,
      attributeLocations,
      bufferUsage: Cesium.BufferUsage.STATIC_DRAW,
    })

    return {
      vertexArray,
      attributeLocations,
    }
  }

  static createQuadGeometry(context, numLon, numLat, numPointOfLine, numVertexPerLine) {
    const numLines = numLon * numLat
    const numVertexs = numVertexPerLine * numLines

    let indices: any = []

    const numFacePerLine = numPointOfLine / 2
    if (numPointOfLine === 1) {
      indices = new Uint32Array((numLon - 1) * (numLat - 1) * 3 * 2)
    } else {
      indices = new Uint32Array(numLines * numFacePerLine * 3 * 2)
    }

    let offset = 0
    try {
      for (let i = 0; i < numVertexs; i++) {
        if (i % numVertexPerLine === 0) {
          const lineID = Math.floor(i / numVertexPerLine)

          if (numPointOfLine === 1) {
            const lineC = lineID % numLon
            const lineR = Math.floor(lineID / numLon);

            if (lineR < numLat - 1 && lineC < numLon - 1) {
              const a = lineC + lineR * numLon
              const b = a + 1
              const c = a + numLon
              const d = c + 1
              indices[offset++] = a; indices[offset++] = b; indices[offset++] = d;
              indices[offset++] = a; indices[offset++] = d; indices[offset++] = c;
            }

          }
          else {
            for (let t = 0; t < numFacePerLine; t++) {
              const a = 2 * t + (0 + lineID * numVertexPerLine)
              const b = a + 1
              const c = 2 * t + (0 + numPointOfLine + lineID * numVertexPerLine)
              const d = c + 1
              indices[offset++] = a; indices[offset++] = b; indices[offset++] = d;
              indices[offset++] = a; indices[offset++] = d; indices[offset++] = c;
            }
          }
        }
      }
    }
    catch (e) {
      console.log(indices.length)
    }

    const geometry = new Cesium.Geometry({
      attributes: {
        position: new Cesium.GeometryAttribute({
          componentDatatype: Cesium.ComponentDatatype.BYTE,
          componentsPerAttribute: 1,
          values: new Uint8Array(numVertexs),
        }),
      },
      indices,
    })

    const attributeLocations = Cesium.GeometryPipeline.createAttributeLocations(geometry);
    const vertexArray = Cesium.VertexArray.fromGeometry({
      context,
      geometry,
      attributeLocations,
      bufferUsage: Cesium.BufferUsage.STATIC_DRAW,
    });

    return {
      vertexArray,
      attributeLocations,
    }
  }
}

export default WeGeometryUtil
